package set_;

import java.util.HashSet;
@SuppressWarnings({"all"})

public class HashSetSource {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add("java");
        hashSet.add("php");
        hashSet.add("java");
        System.out.println("set=" + hashSet);
    }
    /***
     * 1.执行HashSet()
     *  public HashSet(){
     *      map = new HashMap<>();
     *  }
     * 2.执行add()
     * public boolean add(E e) {// e = "java"
     *     return map.put(e, PRESENT)==null;//(static) PRESENT = new Object();
     * }
     * 3.执行put(),执行hash(key) 得到key对应的hash值  算法h = key.hashCode() ^(h >> 16)
     * public V put(K key, V value) {//key = " java" value  = PRESENT 共享
     *         return putVal(hash(key), key, value, false, true);
     *     }
     *4.执行putVal
     * final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
     *                    boolean evict) {
     *         Node<K,V>[] tab; Node<K,V> p; int n, i;//定义辅助变量
     *         //table 就是HashMap的一个数组，类型是Node[]
     *         //if 语句表示如果当前table是null，或者大小 = 0
     *         //第一次扩容到16个空间
     *         if ((tab = table) == null || (n = tab.length) == 0)
     *             n = (tab = resize()).length;
     *         //(1)根据key 得到hash 去计算该key应该放在table表的那个索引位置
     *         //并把这个位置的对象，赋值给p
     *         //(2)判断p是否为null，
     *         //(2.1)如果p为null，表示还没有存放过元素，就创建一个Node
     *         //(2.2)放在位置tab[i] = newNode(hash, key, value, null)
     *
     *         if ((p = tab[i = (n - 1) & hash]) == null)
     *             tab[i] = newNode(hash, key, value, null);
     *         else {
     *         //在需要的局部变量的时候，再创建
     *             Node<K,V> e; K k;//
     *             //如果当前索引位置对应的链表的第一个元素和准备添加的key的hash值一样
     *             //（1）并且满足 准备加入的key 和p 指向的Node结点的key 是同一个对象
     *             //（2）指向的Node结点的key的equals() 和准备加入的key比较后相同
     *             //就不能加入
     *             if (p.hash == hash &&//
     *                 ((k = p.key) == key || (key != null && key.equals(k))))
     *                 e = p;
     *             //再判断p是不是一颗红黑树
     *             //如果是就调用putTreeVal，来进行添加
     *             else if (p instanceof TreeNode)
     *                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
     *             else {//如果table对应索引位置，已经是一个链表，就用for循环比较
     *                   //（1）依次和该链表的每一个元素比较后，都不相同，则加入该链表的最后
     *                   //注意在把元素添加到链表后，立即判断，该链表是否已达到8个结点
     *                   //，就调用treeifBin()对当前这个链表进行树化（转成红黑树）
     *                   //判断 ，该table数组的大小
     *                   if (tab == null||(n = table.length)< MIN_TREEIFY_CAPACITY(64))
     *                              resize();
     *                   //成立就先将table扩容
     *                   //只有上面条件不成立时，才进行转成红黑树
     *                   //（2）依次和该链表的每一个元素比较过程的，如果有相同的情况，就直接break
     *                   //
     *                 for (int binCount = 0; ; ++binCount) {
     *                     if ((e = p.next) == null) {
     *                         p.next = newNode(hash, key, value, null);
     *                         if (binCount >= TREEIFY_THRESHOLD(8) - 1) // -1 for 1st
     *                             treeifyBin(tab, hash);
     *                         break;
     *                     }
     *                     if (e.hash == hash &&
     *                         ((k = e.key) == key || (key != null && key.equals(k))))
     *                         break;
     *                     p = e;
     *                 }
     *             }
     *             if (e != null) { // existing mapping for key
     *                 V oldValue = e.value;
     *                 if (!onlyIfAbsent || oldValue == null)
     *                     e.value = value;
     *                 afterNodeAccess(e);
     *                 return oldValue;
     *             }
     *         }
     *         ++modCount;
     *         if (++size > threshold)
     *             resize();
     *         afterNodeInsertion(evict);
     *         return null;
     *     }
     */
}
